import os
import sys
import time
import json
import random
import hashlib
import requests
from datetime import datetime, timedelta
from PyQt6.QtWidgets import (QDialog, QLabel, QLineEdit, QPushButton, 
                            QVBoxLayout, QHBoxLayout, QMessageBox)
from PyQt6.QtCore import Qt, QTimer

class LicenseValidator:
    """授权验证器，处理应用程序的授权验证流程"""
    
    def __init__(self, db_path="robot_zl.db", server_url="http://47.94.246.41:8111"):
        """初始化验证器"""
        self.db_path = db_path
        self.server_url = server_url
        self.is_validated = False
        
    def validate_on_startup(self, parent=None):
        """应用启动时验证授权"""
        # 检查现有授权状态
        status, message = self.check_license_status()
        
        if status:
            # 已有有效授权
            self.is_validated = True
            # 启动定时上传
            self.start_upload_timer()
            return True, message
        
        # 需要输入授权密钥
        dialog = LicenseDialog(parent, self)
        result = dialog.exec()
        
        if result == QDialog.DialogCode.Accepted:
            self.is_validated = True
            # 启动定时上传
            self.start_upload_timer()
            return True, "授权验证成功"
        else:
            return False, "授权验证失败或取消"
    
    
    def start_upload_timer(self):
        """启动定时上传任务"""
        from PyQt6.QtCore import QTimer
        import sqlite3
        from datetime import datetime
        
        # 设置上传间隔为1分钟（60000毫秒）
        upload_interval = 60 * 1000  # 1分钟
        
        self.upload_timer = QTimer()
        self.upload_timer.timeout.connect(self.upload_data)
        self.upload_timer.start(upload_interval)
        
        # 立即执行一次上传
        self.upload_data()

    def upload_data(self):
        """上传数据到服务器"""
        import requests
        import json
        import sqlite3
        from datetime import datetime
        
        try:
            # 获取授权信息
            with sqlite3.connect(self.db_path) as conn:
                cursor = conn.cursor()
                cursor.execute(
                    """SELECT license_key FROM license_info 
                    WHERE machine_id = ? AND is_valid = 1
                    ORDER BY valid_until DESC LIMIT 1""",
                    (self._get_machine_id(),)
                )
                result = cursor.fetchone()
                
                if not result:
                    print("没有有效的授权信息，无法上传数据")
                    return
                    
                license_key = result[0]
            
            # 准备上传数据
            upload_data = {
                "data": {}
            }
            
            # 从数据库中获取配置数据
            with sqlite3.connect("robot_zl.db") as conn:
                cursor = conn.cursor()
                
                # 获取各个表的数据
                for table in ["gt", "sh", "fl"]:
                    try:
                        cursor.execute(f"SELECT datajson FROM {table} WHERE userId = 1")
                        result = cursor.fetchone()
                        if result and result[0]:
                            try:
                                upload_data["data"][table] = json.loads(result[0])
                            except:
                                upload_data["data"][table] = result[0]
                    except Exception as e:
                        print(f"获取{table}表数据失败: {str(e)}")
            
            # 使用新的API发送数据
            response = requests.post(
                f"{self.server_url}/api/client-data/",
                json=upload_data,
                headers={"X-API-Key": license_key},
                timeout=10
            )
            
            if response.status_code == 200:
                print(f"数据上传成功: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
            else:
                print(f"数据上传失败，状态码: {response.status_code}")
                    
        except Exception as e:
            print(f"上传数据时出错: {str(e)}")

    # 在 LicenseValidator 类中修改相关方法
    def validate_license(self, license_key):
        """验证授权密钥"""
        # 使用新的验证方法
        is_valid = verify_key(license_key)
        
        if is_valid:
            # 授权有效，保存到数据库
            machine_id = self._get_machine_id()
            valid_until = (datetime.now() + timedelta(days=30)).strftime("%Y-%m-%d %H:%M:%S")
            
            with sqlite3.connect(self.db_path) as conn:
                cursor = conn.cursor()
                cursor.execute(
                    """INSERT OR REPLACE INTO license_info 
                    (license_key, machine_id, valid_until, is_valid) 
                    VALUES (?, ?, ?, ?)""",
                    (license_key, machine_id, valid_until, 1)
                )
                conn.commit()
            
            return True, "授权验证成功"
        else:
            return False, "无效的授权密钥"
    
    def validate_license(self, license_key):
        """
        验证授权密钥
        
        Args:
            license_key: 用户输入的授权密钥
            
        Returns:
            (bool, str): (是否有效, 错误信息)
        """
        # 获取机器ID
        machine_id = self._get_machine_id()
        
        # 向服务器验证
        try:
            response = self._validate_with_server(license_key, machine_id)
            
            if response.get("status") == "success":
                # 保存验证结果
                valid_until = response.get("valid_until")
                self._save_license_info(license_key, machine_id, valid_until)
                return True, "授权验证成功，有效期至: " + valid_until
            else:
                return False, response.get("message", "授权验证失败")
                
        except Exception as e:
            return False, f"授权验证失败: {str(e)}"
    
    def _validate_with_server(self, license_key, machine_id):
        """向服务器发送验证请求"""
        try:
            # 使用新的API端点验证
            response = requests.post(
                f"{self.server_url}/api-keys/verify?api_key={license_key}",
                timeout=10
            )
            
            if response.status_code == 200:
                # 验证成功，返回标准格式的响应
                return {
                    "status": "success",
                    "valid_until": (datetime.now() + timedelta(days=30)).strftime("%Y-%m-%d %H:%M:%S"),
                    "message": "授权验证成功"
                }
            else:
                return {
                    "status": "error",
                    "message": f"服务器返回错误: {response.status_code}"
                }
        except requests.RequestException as e:
            raise Exception(f"无法连接到授权服务器: {str(e)}")
    
    def _get_machine_id(self):
        """获取唯一的机器ID（结合多种硬件信息）"""
        # 获取多种硬件信息
        machine_info = []
        
        # CPU信息
        try:
            import platform
            machine_info.append(platform.processor())
        except:
            machine_info.append("unknown_cpu")
            
        # 主板序列号（仅Windows）
        try:
            if platform.system() == "Windows":
                import subprocess
                result = subprocess.check_output('wmic csproduct get uuid', shell=True).decode()
                uuid_result = [x.strip() for x in result.split('\n') if x.strip()][1]
                machine_info.append(uuid_result)
        except:
            machine_info.append("unknown_board")
            
        # 添加MAC地址
        try:
            import uuid
            mac = ':'.join(['{:02x}'.format((uuid.getnode() >> elements) & 0xff) 
                           for elements in range(0, 2*6, 8)][::-1])
            machine_info.append(mac)
        except:
            machine_info.append("unknown_mac")
            
        # 添加用户名和计算机名
        try:
            machine_info.append(platform.node())
            machine_info.append(os.getlogin())
        except:
            machine_info.append("unknown_user")
            
        # 组合并哈希
        machine_str = ":".join(machine_info)
        return hashlib.sha256(machine_str.encode()).hexdigest()
    
    def _save_license_info(self, license_key, machine_id, valid_until):
        """保存授权信息到数据库"""
        import sqlite3
        now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        
        with sqlite3.connect(self.db_path) as conn:
            # 创建表（如果不存在）
            conn.execute("""
                CREATE TABLE IF NOT EXISTS license_info (
                    id INTEGER PRIMARY KEY AUTOINCREMENT,
                    license_key TEXT NOT NULL,
                    machine_id TEXT NOT NULL,
                    valid_until TEXT NOT NULL,
                    last_check TEXT NOT NULL,
                    is_valid INTEGER DEFAULT 1
                )
            """)
            
            # 检查是否已存在此密钥
            cursor = conn.cursor()
            cursor.execute(
                "SELECT id FROM license_info WHERE license_key = ?", 
                (license_key,)
            )
            existing = cursor.fetchone()
            
            if existing:
                # 更新现有记录
                conn.execute(
                    """UPDATE license_info 
                       SET machine_id = ?, valid_until = ?, last_check = ?, is_valid = 1
                       WHERE license_key = ?""",
                    (machine_id, valid_until, now, license_key)
                )
            else:
                # 插入新记录
                conn.execute(
                    """INSERT INTO license_info 
                       (license_key, machine_id, valid_until, last_check, is_valid)
                       VALUES (?, ?, ?, ?, 1)""",
                    (license_key, machine_id, valid_until, now)
                )
    
    def check_license_status(self):
        """检查当前授权状态"""
        import sqlite3
        try:
            with sqlite3.connect(self.db_path) as conn:
                cursor = conn.cursor()
                cursor.execute(
                    """SELECT license_key, valid_until, is_valid 
                       FROM license_info 
                       WHERE machine_id = ? AND is_valid = 1
                       ORDER BY valid_until DESC LIMIT 1""",
                    (self._get_machine_id(),)
                )
                result = cursor.fetchone()
                
                if not result:
                    return False, "未找到有效授权"
                
                license_key, valid_until, is_valid = result
                
                # 检查有效期
                valid_until_date = datetime.strptime(valid_until, "%Y-%m-%d %H:%M:%S")
                if valid_until_date < datetime.now():
                    # 更新状态为无效
                    conn.execute(
                        "UPDATE license_info SET is_valid = 0 WHERE license_key = ?",
                        (license_key,)
                    )
                    return False, "授权已过期，有效期至: " + valid_until
                
                # 定期向服务器验证授权状态
                try:
                    # 每7天验证一次
                    last_check = datetime.strptime(result[2], "%Y-%m-%d %H:%M:%S")
                    days_since_check = (datetime.now() - last_check).days
                    
                    if days_since_check >= 7:
                        # 重新验证
                        response = self._validate_with_server(license_key, self._get_machine_id())
                        if response.get("status") != "success":
                            conn.execute(
                                "UPDATE license_info SET is_valid = 0 WHERE license_key = ?",
                                (license_key,)
                            )
                            return False, "授权已失效: " + response.get("message", "未知错误")
                        
                        # 更新最后检查时间
                        now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                        conn.execute(
                            "UPDATE license_info SET last_check = ? WHERE license_key = ?",
                            (now, license_key)
                        )
                except:
                    # 如果网络验证失败，仍然使用本地缓存
                    pass
                
                days_left = (valid_until_date - datetime.now()).days
                return True, f"授权有效，还剩 {days_left} 天到期"
                
        except Exception as e:
            return False, f"检查授权状态出错: {str(e)}"


class LicenseDialog(QDialog):
    """授权密钥输入对话框"""
    
    def __init__(self, parent, validator):
        super().__init__(parent)
        self.validator = validator
        self.setWindowTitle("授权验证")
        self.setFixedSize(400, 200)
        self.setWindowFlags(self.windowFlags() & ~Qt.WindowType.WindowContextHelpButtonHint)
        
        self.setup_ui()
    
    def setup_ui(self):
        """设置UI组件"""
        layout = QVBoxLayout()
        
        # 标题
        title_label = QLabel("请输入授权密钥")
        title_label.setStyleSheet("font-size: 16px; font-weight: bold;")
        layout.addWidget(title_label)
        
        # 说明
        info_label = QLabel("每个授权密钥只能在一台计算机上使用。\n请输入有效的授权密钥继续使用本软件。")
        layout.addWidget(info_label)
        
        # 输入框
        self.key_input = QLineEdit()
        self.key_input.setPlaceholderText("")
        layout.addWidget(self.key_input)
        
        # 按钮
        button_layout = QHBoxLayout()
        
        self.validate_button = QPushButton("验证")
        self.validate_button.clicked.connect(self.validate_license)
        
        cancel_button = QPushButton("取消")
        cancel_button.clicked.connect(self.reject)
        
        button_layout.addWidget(self.validate_button)
        button_layout.addWidget(cancel_button)
        
        layout.addLayout(button_layout)
        self.setLayout(layout)
    
    def validate_license(self):
        """验证授权密钥"""
        license_key = self.key_input.text().strip()
        
        if not license_key:
            QMessageBox.warning(self, "错误", "请输入授权密钥")
            return
        
        # 显示正在验证
        self.validate_button.setEnabled(False)
        self.validate_button.setText("正在验证...")
        QTimer.singleShot(1000, lambda: self._perform_validation(license_key))
    
    def _perform_validation(self, license_key):
        """执行验证逻辑"""
        status, message = self.validator.validate_license(license_key)
        
        if status:
            QMessageBox.information(self, "成功", message)
            self.accept()
        else:
            QMessageBox.warning(self, "验证失败", message)
            self.validate_button.setEnabled(True)
            self.validate_button.setText("验证")


# 生成授权密钥的辅助函数（仅用于开发/测试）
def generate_license_key():
    """生成一个随机的授权密钥"""
    parts = []
    for _ in range(5):
        # 生成5个字符的随机字符串
        chars = ''.join(random.choices('ABCDEFGHJKLMNPQRSTUVWXYZ23456789', k=5))
        parts.append(chars)
    
    return '-'.join(parts)


# 测试代码
if __name__ == "__main__":
    from PyQt6.QtWidgets import QApplication
    
    app = QApplication(sys.argv)
    
    # 生成测试密钥
    print("测试密钥:", generate_license_key())
    
    # 测试验证
    validator = LicenseValidator()
    status, message = validator.validate_on_startup()
    
    print(f"验证结果: {status}, {message}")
    
    sys.exit(app.exec())


# 添加定时上传功能
# 在 LicenseValidator 类中添加以下方法


# 验证密钥
def verify_key(api_key):
    response = requests.post(
        "http://47.94.246.41:8111/api-keys/verify",
        json={"api_key": api_key}
    )
    return response.status_code == 200

# 发送数据
def send_data(api_key, data):
    response = requests.post(
        "http://47.94.246.41:8111/client-data/",
        json={"data": data},
        headers={"X-API-Key": api_key}
    )
    return response.json() if response.status_code == 200 else None
